Skip to content

abkhaz: ⟨ҩ⟩ is pharyngealized, and an identical glide twin is not its own vowel context - #768

Merged
christopherthompson81 merged 2 commits into
mainfrom
abkhaz-phonology-residuals
Aug 8, 2026
Merged

abkhaz: ⟨ҩ⟩ is pharyngealized, and an identical glide twin is not its own vowel context#768
christopherthompson81 merged 2 commits into
mainfrom
abkhaz-phonology-residuals

Conversation

@christopherthompson81

Copy link
Copy Markdown
Owner

What

The two genuine engine defects among the referee's residual divergence classes, sorted from the referee's own inconsistencies in docs/abkhaz_phonology_investigation.md:

  1. ⟨ҩ⟩ → [ɥˤ], not plain [ɥ]. The word corpus writes the pharyngealized form ~12:1 — kaikki 50× ɥˤ against 4 bare, and wikipron's one non-definition ҩ-word (ахҩа) agrees. The bare-ɥ rows are the letter definition and the numeral series, which is the referee's demonstrably inconsistent corner (it also devoices б there, against its own б=b definition). Chirikba /ʕʷ/ and Hewitt [ɥˤ] are the same segment. The manifest's stated policy — follow the corpus where the sources disagree — decides it.
  2. Identical glide twins: ⟨у⟩/⟨и⟩ count each other as vowel context, so ⟨уу⟩ made both glides — асууари read as[ww]ari. A twin on the right no longer counts, so the first is syllabic: асууари → asuwari, диит → dijtʼ (was djjtʼ), Russian -ии → ij. Mixed runs (аиуит → ajwjtʼ) unchanged.

Plus two kaikki notation folds (ʏ for ⟨ы⟩ after ɥˤ; e̞).

Verification

  • Referee: kaikki 641 → 676 (69.1%), raw 389 → 409. Primary 170 → 166 — all four losses are the Ҩ/ҩ definition rows and the bare-ɥ numerals, i.e. the corner the change deliberately overrules; net +31 across both referees.
  • Corpus: 347/404 rows changed (⟨ҩ⟩ is everywhere). Mechanically verified — strip ˤ from the after side and diff — that every changed row is one of the two intended classes; the 47 residuals are all ⟨ии⟩→[ij]. DROP steady at 33, no leaks.
  • Documented-and-left (with greps): the referee's phonemic-analysis rows ([i]=əj, [e]=aj), the devoiced numeral series, dropped contrastive ʰ/ʼ in single rows, and the Гь→c-family definitions already rejected in core/ipa: ⟨ɑ ɒ ʏ⟩ join the nucleus class — stress was vanishing, bhojpuri +125 words #752.
  • npm run ci green (3157 tests). fr/ht keep their plain ɥ; ɥ is in no shared vowel class.

🤖 Generated with Claude Code

https://claude.ai/code/session_012Lc3WnUgogC7okV7n53vjr

… own vowel context

The word corpus writes [ɥˤ] for ⟨ҩ⟩ ~12:1 (kaikki 50× vs 4; wikipron agrees
outside the definition rows); the bare-ɥ rows are the letter definition and
the numeral series — the same inconsistent corner that devoices б. Chirikba
/ʕʷ/, Hewitt [ɥˤ]. And ⟨уу⟩/⟨ии⟩ made BOTH letters glides because у/и count
each other as vowel context — асууари read as[ww]ari; the first twin is now
syllabic (asuwari, dijtʼ), mixed runs unchanged.

Two notation folds (kaikki ʏ for ы after ɥˤ, e̞). Referee: kaikki 641 → 676
(69.1%); primary 170 → 166, all four losses in the definition/numeral corner.
Corpus: 347/404 rows changed, mechanically verified to be only the two
intended classes; DROP steady, no leaks.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012Lc3WnUgogC7okV7n53vjr
…fixes

The twin patch was keyed on letter identity, which fixed only uu-after-
consonant: ауу still read a[ww] and адиуан read adjwan against the referee
own adiwan. The general rule — left context is the realized previous phone,
right context excludes an undecided у/и — repairs every nucleus-free glide
run: 187/404 corpus rows change, all of them wj→uj / jw→iw (уи "that" had no
nucleus; Хьиуитт was χʲjwjtʼtʼ). kaikki 676 → 677.

Also: ҩ+apostrophe no longer doubles the pharyngealizer (ɥˤˤ); the dead e̞
fold is removed (BACKBONE strips U+031E first) and ʏ→ə is context-limited to
post-ɥˤ; the vowelLetters comment, the referee-floor comment, the catalogue
row and the test comments now state the current rule and numbers, with the
no-referee pins marked as invariant pins.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012Lc3WnUgogC7okV7n53vjr
@christopherthompson81
christopherthompson81 merged commit c38ecbf into main Aug 8, 2026
@christopherthompson81
christopherthompson81 deleted the abkhaz-phonology-residuals branch August 8, 2026 19:24
christopherthompson81 added a commit that referenced this pull request Aug 9, 2026
…t (and refresh ab)

`tools/language-catalogue/derive-normalization.py` decides the `normalization` column from exactly
two things — does the engine directory have a `normalize.ts`, and does the engine call it. pcm's
treatment (#781) put its pre-tokenizer rewrites INLINE in naija.ts, so the column stayed empty and
pcm read as UNTREATED in the planning query the catalogue exists to serve. Typing `done` into the
TSV would have been overwritten on the next run.

⚠ Of the 62 engine DIRECTORIES that use the symbol tier (73 registry codes, several sharing a
directory), naija was the ONLY one with no normalize.ts — checked, not assumed. So this is pcm
being unconventional, not the tool being narrow, and the fix is to be conventional rather than to
teach the tool a second pattern it would then have to keep matching.

Moves the abbreviation expansion (a text rewrite, the same slot Hausa's `normalizeHausa` occupies)
into src/languages/naija/normalize.ts. The SYMBOL tier stays in naija.ts with the engine data, as it
does for ha/af/ur. No behaviour change: 3192 tests unchanged, and the call site is still
SYMBOLS(normalizeNaija(input)) — the order was deliberate.

⚠ THE .db REBUILD IS NOT A TWO-CELL CHANGE. main's committed languages.db did not match main's own
catalogue.tsv: a fresh build differs on 60 rows, staleness accumulated because the TSV has been
edited (e.g. #768/#769 rewrote ab's notes) without rebuilding the binary. This commit's .db is
byte-identical to a fresh build, so it also flushes those 59 unrelated rows — which is why the
binary diff is large for a change described as two cells.

Regenerating the column also picked up a second stale cell unrelated to this work: `ab` (Abkhaz)
has had a normalize.ts since its own treatment landed and was still reported as untreated. Both are
now `done` — 82 → 83, (none) 113 → 112.

The `pr` column is left empty, matching ha and ab: it carries a value in only 7 of 212 rows and
three of those hold stray note text, so it is not a maintained convention to opt into here.

⚠ The derivation and the .db build are both hand-run, which is how ab and the 60 rows drifted. A
`--check` gate in `npm run ci` (the shape check:package already uses) would catch both classes;
flagged rather than done here.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01J9yuDGsezBBo5myS3AeN7D
christopherthompson81 added a commit that referenced this pull request Aug 9, 2026
…t (and refresh ab) (#782)

`tools/language-catalogue/derive-normalization.py` decides the `normalization` column from exactly
two things — does the engine directory have a `normalize.ts`, and does the engine call it. pcm's
treatment (#781) put its pre-tokenizer rewrites INLINE in naija.ts, so the column stayed empty and
pcm read as UNTREATED in the planning query the catalogue exists to serve. Typing `done` into the
TSV would have been overwritten on the next run.

⚠ Of the 62 engine DIRECTORIES that use the symbol tier (73 registry codes, several sharing a
directory), naija was the ONLY one with no normalize.ts — checked, not assumed. So this is pcm
being unconventional, not the tool being narrow, and the fix is to be conventional rather than to
teach the tool a second pattern it would then have to keep matching.

Moves the abbreviation expansion (a text rewrite, the same slot Hausa's `normalizeHausa` occupies)
into src/languages/naija/normalize.ts. The SYMBOL tier stays in naija.ts with the engine data, as it
does for ha/af/ur. No behaviour change: 3192 tests unchanged, and the call site is still
SYMBOLS(normalizeNaija(input)) — the order was deliberate.

⚠ THE .db REBUILD IS NOT A TWO-CELL CHANGE. main's committed languages.db did not match main's own
catalogue.tsv: a fresh build differs on 60 rows, staleness accumulated because the TSV has been
edited (e.g. #768/#769 rewrote ab's notes) without rebuilding the binary. This commit's .db is
byte-identical to a fresh build, so it also flushes those 59 unrelated rows — which is why the
binary diff is large for a change described as two cells.

Regenerating the column also picked up a second stale cell unrelated to this work: `ab` (Abkhaz)
has had a normalize.ts since its own treatment landed and was still reported as untreated. Both are
now `done` — 82 → 83, (none) 113 → 112.

The `pr` column is left empty, matching ha and ab: it carries a value in only 7 of 212 rows and
three of those hold stray note text, so it is not a maintained convention to opt into here.

⚠ The derivation and the .db build are both hand-run, which is how ab and the 60 rows drifted. A
`--check` gate in `npm run ci` (the shape check:package already uses) would catch both classes;
flagged rather than done here.


Claude-Session: https://claude.ai/code/session_01J9yuDGsezBBo5myS3AeN7D

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant